import axios from 'axios';
import qs from 'qs';
import { useEffect, useState } from 'react';
import { updateLoading } from 'src/store/app/app.reducer';
import { Modal } from 'antd';

let dispatch;
const store = import('src/store/index.js');
store.then(function (module) {
  dispatch = module.default.dispatch;
});

const ax = axios.create();

ax.defaults = Object.assign(ax.defaults, {
  baseURL: process.env.REACT_APP_BASE_URL,
  method: 'post',
  timeout: 60 * 1000,
});
const loadingAy = [];

function closeLoading() {
  // 关闭遮罩
  if (loadingAy.length === 1) {
    dispatch(updateLoading(false));
  }
  loadingAy.length--;
}

function showLoading() {
  /* 打开遮罩 */
  dispatch(updateLoading(true));
  return new Date().getTime();
}

function showError(msg, status) {
  /**
   * 提示错误
   * @msg 错误消息
   * @status 状态码
   * */
  const msgMap = new Map([
    [/^401$/, '您没有访问权限'],
    [/^403$/, '您没有访问权限'],
    [/^404$/, '您请求的服务不存在'],
    [/^4\d{2}$/, '您请求的方式不正确'],
    [/^501$/, '服务器不支持此类请求'],
    [/^502$/, '服务器网关出错，请稍后重试'],
    [/^503$/, '服务器正在重启，请稍后重试'],
    [/^503$/, '服务器网关超时，请稍后重试'],
    [/^503$/, '服务器不支持此请求协议'],
    [/^5\d{2}$/, '服务器出错，请稍后重试'],
  ]);
  let errorMsg = msg || '请求失败';
  for (const [key, value] of msgMap) {
    if (key.test(status)) {
      errorMsg = value;
      break;
    }
  }
  // toast.error(errorMsg, {
  //   toastId: 'request',
  //   position: 'top-center',
  //   theme: 'colored',
  //   // autoClose: 2000,
  //   autoClose: false,
  //   hideProgressBar: false,
  //   closeOnClick: true,
  //   pauseOnHover: true,
  //   draggable: true,
  //   progress: undefined,
  // });
  Modal.error({
    title: '提示',
    content: errorMsg,
  });
}

ax.interceptors.request.use(
  (config) => {
    if (config.headers && !config.noToken) {
      config.headers.JINJUTOKEN = localStorage.getItem('token');
    }
    if (!config.noLoading) {
      loadingAy.push(showLoading());
    }
    return config;
  },
  (error) => {
    if (!error.config.noLoading) {
      closeLoading();
    }
    showError(error);
    return {
      success: false,
    };
  },
);

ax.interceptors.response.use(
  (response) => {
    const { config, data } = response;
    // 关闭遮罩
    if (!config.noLoading) {
      closeLoading();
    }
    const { success, msg, status } = data;
    // 401不再提示错误
    if (status === '401') {
      if (window.location.pathname.replace(process.env.PUBLIC_URL, '') !== '/login') {
        window.location.href = `${process.env.PUBLIC_URL}/login`;
      }
    } else if (!(config && config.noToast)) {
      if (!success) {
        showError(msg);
      }
    }
    if (config && config.returnResponse) {
      return response;
    }
    return response.data;
  },
  (error) => {
    if (!error.config.noLoading) {
      closeLoading();
    }
    // 状态码
    let status;
    if (error && error.status) {
      status = error.status;
    }
    showError(error.data, status);
    return {
      success: false,
    };
  },
);

const axGet = function (url, params, options) {
  return ax({
    headers: { 'content-type': 'application/x-www-form-urlencoded,charset=UTF-8' },
    method: 'get',
    url,
    params,
    ...options,
  });
};

const axPost = function (url, data, params, options) {
  return ax({
    method: 'post',
    url,
    data: qs.stringify(data),
    params,
    ...options,
  });
};

const axPostJson = function (url, data, params, options) {
  return ax({
    method: 'post',
    url,
    data,
    params,
    ...options,
  });
};

const useRequest = function (fn, dep = []) {
  /**
   *  hook
   *  @param fn -需要查询的函数
   *  @param dep -依赖，如果不填，则只执行一次
   * */
  const [loading, setLoading] = useState(false);
  const [response, setResponse] = useState({
    success: false,
    data: undefined,
  });

  function query() {
    setLoading(true);
    fn().then((res) => {
      setLoading(false);
      if (res.success) {
        setResponse(res);
      }
    });
  }

  useEffect(() => {
    query();
    /* eslint-disable-next-line */
  }, dep);
  return [response, loading, query, setResponse];
};
export default ax;

export { axGet, axPost, axPostJson, useRequest };
